﻿using Pipes.Json;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Data;

namespace Pipes.UnitTest
{
    
    
    /// <summary>
    ///This is a test class for UtilTest and is intended
    ///to contain all UtilTest Unit Tests
    ///</summary>
  [TestClass()]
  public class JsonSerializatonTests
  {


    private TestContext testContextInstance;

    /// <summary>
    ///Gets or sets the test context which provides
    ///information about and functionality for the current test run.
    ///</summary>
    public TestContext TestContext
    {
      get
      {
        return testContextInstance;
      }
      set
      {
        testContextInstance = value;
      }
    }

    #region Additional test attributes
    // 
    //You can use the following additional attributes as you write your tests:
    //
    //Use ClassInitialize to run code before running the first test in the class
    //[ClassInitialize()]
    //public static void MyClassInitialize(TestContext testContext)
    //{
    //}
    //
    //Use ClassCleanup to run code after all tests in a class have run
    //[ClassCleanup()]
    //public static void MyClassCleanup()
    //{
    //}
    //
    //Use TestInitialize to run code before running each test
    //[TestInitialize()]
    //public void MyTestInitialize()
    //{
    //}
    //
    //Use TestCleanup to run code after each test has run
    //[TestCleanup()]
    //public void MyTestCleanup()
    //{
    //}
    //
    #endregion


    /// <summary>
    ///A test for Serialize
    ///</summary>
    [TestMethod()]
    public void SerializeObjectTest()
    {
      Account account = new Account
      {
        Email = "james@example.com",
        Active = true,
        CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
        Roles = new List<string>
          {
            "User",
            "Admin"
          }
      };

      using (var writer = new System.IO.StringWriter())
      {
        new JsonTextWriter(writer).Serialize(account).Flush();
        Assert.AreEqual("{\"Email\":\"james@example.com\",\"Active\":true,\"CreatedDate\":\"2013-01-20T00:00:00Z\",\"Roles\":[\"User\",\"Admin\"]}", writer.ToString());
      }
    }

    [TestMethod()]
    public void DeserializeObjectTest()
    {
      Account account = new Account
      {
        Email = "james@example.com",
        Active = true,
        CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
        Roles = new List<string>
          {
            "User",
            "Admin"
          }
      };
      var reader = new IO.StringTextSource("{\"Email\":\"james@example.com\",\"Active\":true,\"CreatedDate\":\"2013-01-20T00:00:00Z\",\"Roles\":[\"User\",\"Admin\"]}").Pipe(new Json.JsonTextReader());
      var result = reader.Deserialize<Account>();
      Assert.AreEqual(account, result);
    }

    [TestMethod()]
    public void SerializeCollectionTest()
    {
      List<string> videogames = new List<string>
      {
        "Starcraft",
        "Halo",
        "Legend of Zelda"
      };

      using (var writer = new System.IO.StringWriter())
      {
        var json = new JsonTextWriter(writer);
        json.Serialize(videogames);
        json.Flush();
        Assert.AreEqual("[\"Starcraft\",\"Halo\",\"Legend of Zelda\"]", writer.ToString());
      }
    }

    [TestMethod()]
    public void SerializeDictionaryTest()
    {
      Dictionary<string, int> points = new Dictionary<string, int>
      {
        { "James", 9001 },
        { "Jo", 3474 },
        { "Jess", 11926 }
      };

      using (var writer = new System.IO.StringWriter())
      {
        var json = new JsonTextWriter(writer);
        json.Serialize(points);
        json.Flush();
        Assert.AreEqual("{\"James\":9001,\"Jo\":3474,\"Jess\":11926}", writer.ToString());
      }
    }

    [TestMethod()]
    public void SerializeDatasetTest()
    {
      DataSet dataSet = new DataSet("dataSet");
      dataSet.Namespace = "NetFrameWork";
      DataTable table = new DataTable();
      DataColumn idColumn = new DataColumn("id", typeof(int));
      idColumn.AutoIncrement = true;

      DataColumn itemColumn = new DataColumn("item");
      table.Columns.Add(idColumn);
      table.Columns.Add(itemColumn);
      dataSet.Tables.Add(table);

      for (int i = 0; i < 2; i++)
      {
        DataRow newRow = table.NewRow();
        newRow["item"] = "item " + i;
        table.Rows.Add(newRow);
      }

      dataSet.AcceptChanges();

      using (var writer = new System.IO.StringWriter())
      {
        var json = new JsonTextWriter(writer);
        json.Serialize(dataSet);
        json.Flush();
        Assert.AreEqual("{\"Table1\":[{\"id\":0,\"item\":\"item 0\"},{\"id\":1,\"item\":\"item 1\"}]}", writer.ToString());
      }
    }

    public class Account
    {
      public string Email { get; set; }
      public bool Active { get; set; }
      public DateTime CreatedDate { get; set; }
      public IList<string> Roles { get; set; }

      public override bool Equals(object obj)
      {
        var account = obj as Account;
        if (account == null) return false;
        return Equals(account);
      }
      public bool Equals(Account obj)
      {
        if (obj.Email == this.Email && obj.Active == this.Active && obj.CreatedDate.ToUniversalTime() == this.CreatedDate.ToUniversalTime() && 
          ((obj.Roles == null && this.Roles == null) || obj.Roles.Count == this.Roles.Count))
        {
          for (int i = 0; i < this.Roles.Count; i++)
          {
            if (this.Roles[i] != obj.Roles[i]) return false;
          }
          return true;
        }
        return false;
      }
    }
  }
}
